package com.cgt.xiaotao.order.util;


public class SnowflakeIdGenerator {
    private final long nodeId;
    private long lastTimestamp = -1L;
    private long lastId = 0L;

    private static final long NODE_BITS = 10L;
    private static final long SEQUENCE_BITS = 12L;
    private static final long MAX_SEQUENCE = ~(-1L << SEQUENCE_BITS);

    public SnowflakeIdGenerator(long nodeId) {
        this.nodeId = nodeId << SEQUENCE_BITS;
    }

    public synchronized long nextId() {
        long timestamp = System.currentTimeMillis();

        if (timestamp < lastTimestamp) {
            throw new RuntimeException("时间回拨");
        }

        if (timestamp == lastTimestamp) {
            long sequence = (lastId + 1) & MAX_SEQUENCE;
            if (sequence == 0) {
                timestamp = tilNextMillis(lastTimestamp);
            }
            lastId = sequence;
        } else {
            lastId = 0;
        }

        lastTimestamp = timestamp;
        return (timestamp << NODE_BITS) | nodeId | lastId;
    }

    private long tilNextMillis(long lastTimestamp) {
        long timestamp = System.currentTimeMillis();
        while (timestamp <= lastTimestamp) {
            timestamp = System.currentTimeMillis();
        }
        return timestamp;
    }
}
